Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

submodule(utility), transforms: collect XSLogs to SimTop.LogPerfEndpoint #3982

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

klin02
Copy link
Member

@klin02 klin02 commented Dec 4, 2024

XSLog depends on LogPerfCtrl declared at Top Module. Previous we annotate such signal as dontTouch, and accessed through Hierarchical name like SimTop.xx by dummy LogPerfHelper.

However, as XSLog is called in many spaces in DUT, which are not visible to each other, especailly some in WhenContext. XS will generate thousands of LogPerfHelper to get same LogPerfCtrl. Too many module instantiations greately slow down compilation speed, especailly in Palladium (more than 5 times slower than same DUT without Log).

This change collect all XSLog to SimTop.LogPerfEndpoint, with LogPerfCtrl directly passed by IO. Some tips as follows:

Not call XSLog inside whenContext. To collect XSLogs, we should access Cond and Data from other module, but data in WhenContext is not accessible even through tap. Use XSLog(cond, pable) instead of when(cond) {XSLog(pable)}. We also add chisel Internal API currentWhen to check that.

Generate Hierarchical Module path through FIRRTL transforms. Sometimes we want to append module path for better debugging. XSCompatibility add a hacky way to use Chisel internal API to get tag of current Module. Then we will replace these tag with path during ChiselStage. Note path can only be acessed after circuit elaboration.

Register and invoke caller of XSPerf and related object. As XSPerf depends on LogPerfCtrl such as dump. We should deferred apply() until collect. So we regirster collect() method when firstly apply XSLog, then XSLog will automatically call XSPerf.collect() method during collection. Note deferred apply is called in another module, so original module tag should be recorded for path generation.

@klin02 klin02 marked this pull request as draft December 4, 2024 06:43
@klin02 klin02 force-pushed the log-collect branch 4 times, most recently from cd3f2bf to 3ea2fa6 Compare December 13, 2024 19:39
@klin02 klin02 changed the title feat(LogPerf): collect Logs after circuit elaboration submodule(utility), transforms: collect XSLogs to SimTop.LogPerfEndpoint Dec 14, 2024
@klin02 klin02 force-pushed the log-collect branch 4 times, most recently from 6cadc8f to d00cf72 Compare December 15, 2024 04:46
stateNext := s_idle
XSError(true.B, s"Unknown state!\n")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If it is really difficult to new XSError to do this, use assert(false.B) instead of simply delete this line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure. I will make a change

As data in WhenContext is not acessible in another module. To support
XSLog collection, we move all XSLog and related signal outside
WhenContext. For example, when(cond1){XSDebug(cond2, pable)} to
XSDebug(cond1 && cond2, pable)
XSLog depends on LogPerfCtrl declared at Top Module. Previous we
annotate such signal as dontTouch, and accessed through Hierarchical
name like SimTop.xx by dummy LogPerfHelper.

However, as XSLog is called in many spaces in DUT, which are not
visible to each other, especailly some in WhenContext. XS will generate
thousands of LogPerfHelper to get same LogPerfCtrl. Too many module
instantiations greately slow down compilation speed, especailly in
Palladium (more than 5 times slower than same DUT without Log).

This change collect all XSLog to SimTop.LogPerfEndpoint, with
LogPerfCtrl directly passed by IO. Some tips as follows:

1. Not call XSLog inside whenContext. To collect XSLogs, we should
access Cond and Data from other module, but data in WhenContext is
not accessible even through tap. Use XSLog(cond, pable) instead of
when(cond) {XSLog(pable)}. We also add chisel Internal API currentWhen
to check that.

2. Generate Hierarchical Module path through FIRRTL transforms.
Sometimes we want to append module path for better debugging.
XSCompatibility add a hacky way to use Chisel internal API to get
tag of current Module. Then we will replace these tag with
path during ChiselStage. Note path can only be acessed after circuit
elaboration.

3. Register and invoke caller of XSPerf and related object. As XSPerf
depends on LogPerfCtrl such as dump. We should deferred apply() until
collect. So we regirster collect() method when firstly apply XSLog,
then XSLog will automatically call XSPerf.collect() method during
collection. Note deferred apply is called in another module, so original
module tag should be recorded for path generation.

4. Concat XSLogs with same condition. Too many fwrites in same module
 will cause UPOPTTHREADS warning with 16-threads Verilator. Consider
 many XSLogs have same condition (especailly XSPerfs), we reuse same
 condition and concat their printables to reduce fwrites. Note we also
 limit size of concatation to 1000 to avoid segmentation fault caused
 by too long printf.
@klin02
Copy link
Member Author

klin02 commented Dec 15, 2024

Related Utility PR OpenXiangShan/Utility#89

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants